package jmu.tools.file.sync.util ;


import java.io.BufferedWriter ;
import java.io.File ;
import java.io.FileWriter ;
import java.io.IOException ;
import java.io.Writer ;
import java.text.SimpleDateFormat ;
import java.util.Date ;
import java.util.HashMap ;
import java.util.Map ;

import org.apache.tools.ant.BuildException ;

public class LogManager
{
    public class Log
    {
        private Writer writer = null ;
        private String file = null ;

        private Log ( final String dir, final Date date, final String prefix )
        {
            file = getFile ( dir, date, prefix ) ;
        }

        public void log ( final String message )
        {
            try
            {
                getWriter ().write ( message ) ;
                getWriter ().flush () ;
            }
            catch ( final IOException e )
            {
                error ( "write fail: " + e.getLocalizedMessage () ) ;
            }
        }

        protected void close ()
        {
            try
            {
                if ( null != getWriter () )
                {
                    getWriter ().close () ;
                }
            }
            catch ( final IOException e )
            {
                // ignore
            }
        }

        private Writer createWriter () throws BuildException
        {
            try
            {
                return new BufferedWriter ( new FileWriter ( file ) ) ;
            }
            catch ( final IOException e )
            {
                throw new BuildException ( "create log failed", e ) ;
            }
        }

        private String getFile ( final String dir, final Date date, final String prefix )
        {
            final Date stamp = (null == date ? new Date () : date) ;
            final String directory = (null == dir) ? "" : dir + File.separator ;
            return directory + "sync-" + LOG_DATE_FORMATTER.format ( stamp )
                    + (null == prefix || prefix.isEmpty () ? "" : "-" + prefix) + ".log" ;
        }

        private Writer getWriter ()
        {
            synchronized ( LOG_DATE_FORMATTER )
            {
                if ( null == writer )
                {
                    writer = createWriter () ;
                }
            }

            return writer ;
        }
    }

    public enum Type
    {
        FILE, FILE_FAIL, DIR, DIR_FAIL
    }

    private static final SimpleDateFormat LOG_DATE_FORMATTER = new SimpleDateFormat ( "yyyyMMdd-hhmmss" ) ;
    private static final String ERROR = "error" ;

    public static void error ( final String message )
    {
        System.out.println ( ERROR + " - " + message ) ;
    }

    private final Map < Type, Log > loggers = new HashMap < Type, Log > () ;
    private final Date date = new Date () ;

    private String dir = null ;

    public LogManager ( final String dir )
    {
        this.dir = dir ;
    }

    public void close ()
    {
        for ( final Type type : loggers.keySet () )
        {
            Log log = loggers.get ( type ) ;
            if ( null != log )
            {
                log.close () ;
            }
        }
        loggers.clear () ;
    }

    public void log ( final Type type, final String message )
    {
        if ( null == type )
        {
            error ( "type is null! can't write message: " + message ) ;
        }
        else
        {
            if ( !loggers.containsKey ( type ) )
            {
                loggers.put ( type, new Log ( dir, date, type.name ().toLowerCase ().replace ( '_', '-' ) ) ) ;
            }

            loggers.get ( type ).log ( message ) ;
        }
    }
}
